PROJ_DIR = $(CURDIR)
BUILD_DIR = $(PROJ_DIR)/build
RELEASE_DIR = $(PROJ_DIR)/bin
SUB_PROJ_CLENT = Client
SUB_PROJ_SERVER = Server
SUB_PROJ_MSGTRANS = MsgTransInThread
SUB_PROJ_TIMER = Timer
SUB_PROJ_USERTHREAD = UserDefineThread

CLIENT_DIR = $(PROJ_DIR)/examples/$(SUB_PROJ_CLENT)
SERVER_DIR = $(PROJ_DIR)/examples/$(SUB_PROJ_SERVER)
MSGTRANS_DIR = $(PROJ_DIR)/examples/$(SUB_PROJ_MSGTRANS)
TIMER_DIR = $(PROJ_DIR)/examples/$(SUB_PROJ_TIMER)
USERTHREAD_DIR = $(PROJ_DIR)/examples/$(SUB_PROJ_USERTHREAD)

PLAT_DIR = $(PROJ_DIR)/xncc_platform
XNCC_LOG_DIR = $(PROJ_DIR)/xncc_log/include
PLAT_CFG_MGR_DIR = $(PLAT_DIR)/cfg_mgr
PLAT_FOUNDATION_DIR = $(PLAT_DIR)/foundation
PLAT_SHARED_DIR = $(PLAT_DIR)/shared
PLAT_MSG_LIST_DIR = $(PLAT_DIR)/msg_list
PLAT_USER_IF_DIR = $(PLAT_DIR)/user_if

STATIC_LINK_OBJS = $(PLAT_DIR)/lib/libxncc_platform.a
XNCC_LOG_STATIC_LIB = $(PROJ_DIR)/xncc_log/lib/libxncc_log.a
BIN_PREFIX = T
CLIENT_EXE = $(RELEASE_DIR)/$(BIN_PREFIX)$(SUB_PROJ_CLENT)
SERVER_EXE = $(RELEASE_DIR)/$(BIN_PREFIX)$(SUB_PROJ_SERVER)
MSGTRANS_EXE = $(RELEASE_DIR)/$(BIN_PREFIX)$(SUB_PROJ_MSGTRANS)
TIMER_EXE = $(RELEASE_DIR)/$(BIN_PREFIX)$(SUB_PROJ_TIMER)
USERTHREAD_EXE = $(RELEASE_DIR)/$(BIN_PREFIX)$(SUB_PROJ_USERTHREAD)

TARGETS = pre $(STATIC_LINK_OBJS) $(CLIENT_EXE) $(SERVER_EXE) $(MSGTRANS_EXE) $(TIMER_EXE) $(USERTHREAD_EXE)

all:$(TARGETS)

pre:
	mkdir -p $(BUILD_DIR)
	mkdir -p $(BUILD_DIR)/$(SUB_PROJ_CLENT)
	mkdir -p $(BUILD_DIR)/$(SUB_PROJ_SERVER)
	mkdir -p $(BUILD_DIR)/$(SUB_PROJ_MSGTRANS)
	mkdir -p $(BUILD_DIR)/$(SUB_PROJ_TIMER)
	mkdir -p $(BUILD_DIR)/$(SUB_PROJ_USERTHREAD)
	mkdir -p $(RELEASE_DIR)
	mkdir -p $(PLAT_DIR)/lib

clean:
	rm -rf $(PROJ_DIR)/build/*.o $(PROJ_DIR)/build/*.d $(CLIENT_EXE) $(SERVER_EXE) $(MSGTRANS_EXE) $(TIMER_EXE) $(USERTHREAD_EXE)

CC = g++
FLAGS = -Wall \
		-Wextra \
 		-Werror \
        -Wconversion \
        -Wno-stringop-truncation \
        -Wno-format-truncation \
        -Wno-unused-parameter \
        -Wold-style-cast \
        -Woverloaded-virtual \
        -Wpointer-arith \
        -Wwrite-strings \
        -std=c++11 -O3 \
        -rdynamic \
        -pthread -MMD -MP

PLAT_INCLUDE_DIR = -I $(XNCC_LOG_DIR) \
				   -I $(PLAT_CFG_MGR_DIR)/inc \
				   -I $(PLAT_FOUNDATION_DIR)/inc \
				   -I $(PLAT_SHARED_DIR)/inc \
				   -I $(PLAT_MSG_LIST_DIR)/inc \
				   -I $(PLAT_USER_IF_DIR)/inc

CLIENT_INCLUDE_DIR = -I $(CLIENT_DIR)/inc -I $(XNCC_LOG_DIR)
SERVER_INCLUDE_DIR = -I $(SERVER_DIR)/inc -I $(XNCC_LOG_DIR)
MSGTRANS_INCLUDE_DIR = -I $(MSGTRANS_DIR)/inc -I $(XNCC_LOG_DIR)
TIMER_INCLUDE_DIR = -I $(TIMER_DIR)/inc -I $(XNCC_LOG_DIR)
USERTHREAD_INCLUDE_DIR = -I $(USERTHREAD_DIR)/inc -I $(XNCC_LOG_DIR)

PLAT_SRC_DIR := $(PLAT_CFG_MGR_DIR)/src
PLAT_SRC_DIR += $(PLAT_FOUNDATION_DIR)/src
PLAT_SRC_DIR += $(PLAT_SHARED_DIR)/src
PLAT_SRC_DIR += $(PLAT_MSG_LIST_DIR)/src
PLAT_SRC_DIR += $(PLAT_USER_IF_DIR)/src

PLAT_OBJS := $(foreach dir, $(PLAT_SRC_DIR), $(addprefix $(BUILD_DIR)/, $(patsubst %.cpp, %.o, $(notdir $(wildcard $(dir)/*.cpp)))))

CLIENT_OBJS := $(addprefix $(BUILD_DIR)/$(SUB_PROJ_CLENT)/, $(patsubst %.cpp, %.o, $(notdir $(wildcard $(CLIENT_DIR)/src/*.cpp))))
SERVER_OBJS := $(addprefix $(BUILD_DIR)/$(SUB_PROJ_SERVER)/, $(patsubst %.cpp, %.o, $(notdir $(wildcard $(SERVER_DIR)/src/*.cpp))))
MSGTRANS_OBJS := $(addprefix $(BUILD_DIR)/$(SUB_PROJ_MSGTRANS)/, $(patsubst %.cpp, %.o, $(notdir $(wildcard $(MSGTRANS_DIR)/src/*.cpp))))
TIMER_OBJS := $(addprefix $(BUILD_DIR)/$(SUB_PROJ_TIMER)/, $(patsubst %.cpp, %.o, $(notdir $(wildcard $(TIMER_DIR)/src/*.cpp))))
USERTHREAD_OBJS := $(addprefix $(BUILD_DIR)/$(SUB_PROJ_USERTHREAD)/, $(patsubst %.cpp, %.o, $(notdir $(wildcard $(USERTHREAD_DIR)/src/*.cpp))))

ALL_OBJS := $(PLAT_OBJS)
ALL_OBJS += $(CLIENT_OBJS)
ALL_OBJS += $(SERVER_OBJS)
ALL_OBJS += $(MSGTRANS_OBJS)
ALL_OBJS += $(TIMER_OBJS)
ALL_OBJS += $(USERTHREAD_OBJS)

DEPENDS := $(foreach objs, $(ALL_OBJS), $(patsubst %.o, %.d, $(objs)))

test:
	@echo $(PLAT_OBJS)
	@echo $(DEPENDS)


$(STATIC_LINK_OBJS):$(PLAT_OBJS)
	gcc-ar rcs $@ $^

$(CLIENT_EXE):$(CLIENT_OBJS) $(STATIC_LINK_OBJS) $(XNCC_LOG_STATIC_LIB)
	$(CC) $(FLAGS) -o $@ $^

$(SERVER_EXE):$(SERVER_OBJS) $(STATIC_LINK_OBJS) $(XNCC_LOG_STATIC_LIB)
	$(CC) $(FLAGS) -o $@ $^

$(MSGTRANS_EXE):$(MSGTRANS_OBJS) $(STATIC_LINK_OBJS) $(XNCC_LOG_STATIC_LIB)
	$(CC) $(FLAGS) -o $@ $^

$(TIMER_EXE):$(TIMER_OBJS) $(STATIC_LINK_OBJS) $(XNCC_LOG_STATIC_LIB)
	$(CC) $(FLAGS) -o $@ $^

$(USERTHREAD_EXE):$(USERTHREAD_OBJS) $(STATIC_LINK_OBJS) $(XNCC_LOG_STATIC_LIB)
	$(CC) $(FLAGS) -o $@ $^

$(BUILD_DIR)/$(SUB_PROJ_CLENT)/%.o:$(CLIENT_DIR)/src/%.cpp $(BUILD_DIR)/$(SUB_PROJ_CLENT)/%.d makefile | $(BUILD_DIR)/$(SUB_PROJ_CLENT)
	$(CC) $(FLAGS) $(CLIENT_INCLUDE_DIR) -I $(PLAT_USER_IF_DIR)/inc -o $@ -c $< 

$(BUILD_DIR)/$(SUB_PROJ_SERVER)/%.o:$(SERVER_DIR)/src/%.cpp $(BUILD_DIR)/$(SUB_PROJ_SERVER)/%.d makefile | $(BUILD_DIR)/$(SUB_PROJ_SERVER)
	$(CC) $(FLAGS) $(SERVER_INCLUDE_DIR) -I $(PLAT_USER_IF_DIR)/inc -o $@ -c $< 

$(BUILD_DIR)/$(SUB_PROJ_MSGTRANS)/%.o:$(MSGTRANS_DIR)/src/%.cpp $(BUILD_DIR)/$(SUB_PROJ_MSGTRANS)/%.d makefile | $(BUILD_DIR)/$(SUB_PROJ_MSGTRANS)
	$(CC) $(FLAGS) $(MSGTRANS_INCLUDE_DIR) -I $(PLAT_USER_IF_DIR)/inc -o $@ -c $< 

$(BUILD_DIR)/$(SUB_PROJ_TIMER)/%.o:$(TIMER_DIR)/src/%.cpp $(BUILD_DIR)/$(SUB_PROJ_TIMER)/%.d makefile | $(BUILD_DIR)/$(SUB_PROJ_TIMER)
	$(CC) $(FLAGS) $(TIMER_INCLUDE_DIR) -I $(PLAT_USER_IF_DIR)/inc -o $@ -c $< 

$(BUILD_DIR)/$(SUB_PROJ_USERTHREAD)/%.o:$(USERTHREAD_DIR)/src/%.cpp $(BUILD_DIR)/$(SUB_PROJ_USERTHREAD)/%.d makefile | $(BUILD_DIR)/$(SUB_PROJ_USERTHREAD)
	$(CC) $(FLAGS) $(USERTHREAD_INCLUDE_DIR) -I $(PLAT_USER_IF_DIR)/inc -o $@ -c $< 

$(BUILD_DIR)/%.o:$(PLAT_DIR)/*/src/%.cpp $(BUILD_DIR)/%.d makefile | $(BUILD_DIR)
	$(CC) $(FLAGS) $(PLAT_INCLUDE_DIR) -o $@ -c $< 

$(BUILD_DIR)/%.d: ;
$(BUILD_DIR)/*/%.d: ;

$(BUILD_DIR) $(BUILD_DIR)/$(SUB_PROJ_CLENT) $(BUILD_DIR)/$(SUB_PROJ_SERVER) $(BUILD_DIR)/$(SUB_PROJ_MSGTRANS) $(BUILD_DIR)/$(SUB_PROJ_TIMER) $(BUILD_DIR)/$(SUB_PROJ_USERTHREAD):
	@mkdir -p $@

ifeq ($(filter $(MAKECMDGOALS), clean test pre), )
-include $(DEPENDS)
endif

